﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace UFrame
{
    /// <summary>
    /// 检查json输出， 不支持嵌套类
    /// 支持相同属性赋值, 不存在的属性不报错
    /// </summary>
    [Serializable]
    public class MapJsonKeyValue
    {
        public string className;
        public List<MapJsonField> fields = new List<MapJsonField>();

        public void Clear()
        {
            className = string.Empty;
            fields.Clear();
        }

        public MapJsonKeyValue AssignIn(object o)
        {
            var type = o.GetType();
            className = type.FullName;
            fields.Clear();
            var typeFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
            foreach (var item in typeFields)
            {
                MapJsonField f = new MapJsonField();
                f.field = item.Name;
                f.value = item.GetValue(o);
                fields.Add(f);
            }

            return this;
        }

        public object AssignOut()
        {
            if (string.IsNullOrEmpty(className))
            {
                return null;
            }

            Type t = AssemblyTool.SearchType(className);
            object o = Activator.CreateInstance(t);

            var type = o.GetType();
            var typeFields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);


            foreach (var item in typeFields)
            {
                MapJsonField f = new MapJsonField();

                for (int i = 0; i < fields.Count; i++)
                {
                    if (fields[i].field == item.Name)
                    {
                        RefTools.SetFieldValue(item, o, fields[i].value);
                        //item.SetValue(o, fields[i].value);
                        break;
                    }
                }
            }

            return o;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            string json = "{{{0}}}";

            if (fields.Count > 0)
            {
                sb.AppendLine("\"className\"" + ":" + "\"" + className + "\",");
            }
            else
            {
                sb.AppendLine("\"className\"" + ":" + "\"" + className + "\"");
            }

            for (int i = 0; i < fields.Count; i++)
            {
                MapJsonField item = fields[i];
                MapJsonField f = new MapJsonField();
                string v = null;


                if (item.value == null)
                {
                    v = "null";
                }
                else
                {
                    string fieldTypeName = item.value.GetType().Name;
                    if (fieldTypeName == "Int32" || fieldTypeName == "Int64" || item.value == "Double" ||
                        item.value == "Single" || item.value == "Int16")
                    {
                        v = item.value.ToString();
                    }

                    if (item.value is string)
                    {
                        v = "\"" + item.value.ToString() + "\"";
                    }
                }


                if (i == fields.Count - 1)
                {
                    sb.AppendLine("\"" + item.field + "\"" + ":" + v);
                }
                else
                {
                    sb.AppendLine("\"" + item.field + "\"" + ":" + v + ",");
                }
            }

            return string.Format(json, sb.ToString());
        }
    }

    [Serializable]
    public class MapJsonField
    {
        public string field;
        public object value;
    }
}